---
title: SAIF.Business.Policy business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-21
library: SAIF.Business.Policy
reference_type: package
---

# SAIF.Business.Policy business rules

This page captures business rules enforced by this library.

## BR-POL-001 Hazard group effective-dating

| Field | Value |
| --- | --- |
| **Statement** | A hazard group is returned only when the requested effective date falls on/after its `EFFECTIVE_DATE` and before its `EXPIRATION_DATE`; a missing expiration date is treated as open-ended (`NVL(H.EXPIRATION_DATE, :EffectiveDate + 1)`). |
| **Trigger** | Hazard group retrieval (`GetHazardGroups`) |
| **Enforcement** | `clsHazardGroupCollection.Criteria.BuildWhere` / `RetrieveSQL` |
| **Outcome** | Only hazard groups in force on the supplied date are loaded. |
| **Tables** | [HAZARD_GROUP](database-tables.md#hazard_group) |
| **SQL** | [SQL-002](sql/SQL-002-hazard-group-retrieve.md) |
| **Source** | SAIF.Business.Policy/clsHazardGroupCollection.vb |

---

## BR-POL-002 Hazard group data is read-only

| Field | Value |
| --- | --- |
| **Statement** | Hazard group data is read-only: the collection forbids edit and remove, is never savable, and every non-retrieve SQL property raises `ApplicationException(clsConstants.Messages.InvalidSQLProperty)`. |
| **Trigger** | Any attempt to create/update/delete a hazard group |
| **Enforcement** | `clsHazardGroupCollection.New`, `.IsSavable`; `Criteria.CreateSQL/InsertSQL/UpdateSQL/DeleteSQL` in both `clsHazardGroup.vb` and `clsHazardGroupCollection.vb` |
| **Outcome** | Persistence attempts fail fast; the library is query-only for this entity. |
| **Source** | SAIF.Business.Policy/clsHazardGroup.vb, SAIF.Business.Policy/clsHazardGroupCollection.vb |

---

## BR-POL-003 Hazard group identity

| Field | Value |
| --- | --- |
| **Statement** | Two hazard groups are the same when their `HazardGroupID` values are equal; the id is also the hash and string representation. |
| **Trigger** | Equality, `Contains`, `ItemByKey`, `Remove` |
| **Enforcement** | `clsHazardGroup.Equals/GetHashCode/ToString` |
| **Outcome** | Consistent identity semantics across collection operations. |
| **Source** | SAIF.Business.Policy/clsHazardGroup.vb |

---

## BR-POL-004 Market type code classification

| Field | Value |
| --- | --- |
| **Statement** | Market type code `"ARP"` means Assigned Risk and `"VOL"` means Voluntary; any other value (including an absent one) is Unassigned. |
| **Trigger** | Market type conversion / `PolicyInformation.MarketType` |
| **Enforcement** | `Enums.ConvertMarketType` |
| **Outcome** | Unknown codes degrade to `MarketTypes.Unassigned` rather than raising. |
| **Tables** | [POLICY](database-tables.md#policy) |
| **SQL** | [SQL-004](sql/SQL-004-get-market-type.md) |
| **Source** | SAIF.Business.Policy/Enums.vb |

---

## BR-POL-005 Policy ownership determination

| Field | Value |
| --- | --- |
| **Statement** | A policy is owned by WCIS when `pk73102_policy.does_wcis_own_submission` returns true; otherwise it is owned by SAIFQuote. |
| **Trigger** | `PolicyInformation.GetPolicyOwnershipSystem` |
| **Enforcement** | `PolicyInformation.GetPolicyOwnershipSystem` |
| **Outcome** | Callers learn which system may modify the policy. |
| **Tables** | [DUAL](database-tables.md#dual) |
| **SQL** | [SQL-005](sql/SQL-005-get-policy-ownership-system.md) |
| **Source** | SAIF.Business.Policy/PolicyInformation.vb |

---

## BR-POL-006 Information page printed status

| Field | Value |
| --- | --- |
| **Statement** | A policy period's information page counts as printed only when a `P401` endorsement exists for that policy/period with a non-null `printed_date` and the returned policy number matches the requested one. |
| **Trigger** | `PolicyInformation.IsInformationPagePrinted` |
| **Enforcement** | `PolicyInformation.IsInformationPagePrinted` |
| **Outcome** | `True` only for issued (printed) periods. |
| **Tables** | [ENDORSEMENT](database-tables.md#endorsement) |
| **SQL** | [SQL-006](sql/SQL-006-is-information-page-printed.md) |
| **Source** | SAIF.Business.Policy/PolicyInformation.vb |

---

## BR-POL-007 Current premium history set selection

| Field | Value |
| --- | --- |
| **Statement** | The current premium history set is the highest `prem_hist_set_id` for the policy/period restricted to premium history types `'1'` and `'3'`; when none exists the result is `0`. |
| **Trigger** | `PolicyInformation.MaxPremiumHistorySetId` |
| **Enforcement** | `PolicyInformation.MaxPremiumHistorySetId` |
| **Outcome** | A safe `0` sentinel instead of a null-reference failure. |
| **Tables** | [PREM_HIST_SUMMARY](database-tables.md#prem_hist_summary) |
| **SQL** | [SQL-007](sql/SQL-007-max-prem-hist-set-id.md) |
| **Source** | SAIF.Business.Policy/PolicyInformation.vb |

---

## BR-POL-008 Minimum premium fail-soft behavior

| Field | Value |
| --- | --- |
| **Statement** | Minimum premium is whatever `pk73069_rating_procs.get_minimum_expense_constant` returns; if the call fails or returns nothing, minimum premium is `0` and the failure is not surfaced.* |
| **Trigger** | `PolicyInformation.PolicyMinimumPremium` |
| **Enforcement** | `PolicyInformation.PolicyMinimumPremium` (empty `Catch`) |
| **Outcome** | Callers cannot distinguish "no minimum premium" from "lookup failed" — a silent-failure risk.* |
| **SQL** | [SQL-011](sql/SQL-011-policy-minimum-premium.md) |
| **Source** | SAIF.Business.Policy/PolicyInformation.vb |

---

## BR-POL-009 Policy effective date derivation

| Field | Value |
| --- | --- |
| **Statement** | The policy's effective date is the effective date of its latest policy period. |
| **Trigger** | `PolicyInformation.MaxPolicyEffectiveDate` |
| **Enforcement** | `PolicyInformation.SQL.PolicyEffectiveDate` |
| **Outcome** | Returns the most recent period's effective date. |
| **Tables** | [POLICY_PERIOD](database-tables.md#policy_period) |
| **SQL** | [SQL-008](sql/SQL-008-policy-effective-date.md) |
| **Source** | SAIF.Business.Policy/PolicyInformation.vb |

---

## BR-POL-010 Dual-source period date resolution

| Field | Value |
| --- | --- |
| **Statement** | Period expiration date and anniversary rating date must be resolved across both WCIS and non-WCIS period stores (`POLICY_PERIOD` `UNION` `POLICY_PERIOD_NON_WCIS`). |
| **Trigger** | `PolicyInformation.PolicyPeriodExpirationDate`, `PolicyInformation.AnniversaryRateDate` |
| **Enforcement** | `PolicyInformation.SQL.PolicyPeriodExpirationDate`, `.PolicyPeriodARD` |
| **Outcome** | Legacy/converted policies resolve the same as WCIS policies. |
| **Tables** | [POLICY_PERIOD](database-tables.md#policy_period), [POLICY_PERIOD_NON_WCIS](database-tables.md#policy_period_non_wcis) |
| **SQL** | [SQL-009](sql/SQL-009-policy-period-anniversary-rate-date.md), [SQL-010](sql/SQL-010-policy-period-expiration-date.md) |
| **Source** | SAIF.Business.Policy/PolicyInformation.vb |

---

## BR-POL-011 Non-applicable adjusted-rate factor neutrality

| Field | Value |
| --- | --- |
| **Statement** | An adjusted-rate factor that does not apply to a given provider must contribute `1`, not `0`, so the cumulative factor is unchanged. |
| **Trigger** | Adjusted-rate factor computation by implementers |
| **Enforcement** | `AdjustedRates.NonApplicableAdjustedRateFactor` constant + interface remarks (contract-level rule; enforcement is in implementing libraries)* |
| **Outcome** | Non-applicable factors are neutral in multiplication. |
| **Source** | SAIF.Business.Policy/CodeMaps/iAdjustedRateFactor.vb |

---

## BR-POL-012 Benefit jurisdiction code recognition

| Field | Value |
| --- | --- |
| **Statement** | Only benefit jurisdiction codes `"S"` (State) and `"F"` (Federal) are recognised; other rows in `BENEFIT_JURISDICTION_CODE` are ignored. |
| **Trigger** | Code map construction (`CodeMaps.GetBenefitJurisdictionCodeMap`) |
| **Enforcement** | `clsBenefitJurisdictionCodeMap.New` |
| **Outcome** | Unrecognised codes are absent from the map. |
| **Tables** | [BENEFIT_JURISDICTION_CODE](database-tables.md#benefit_jurisdiction_code) |
| **SQL** | [SQL-001](sql/SQL-001-benefit-jurisdiction-code-lookup.md) |
| **Source** | SAIF.Business.Policy/CodeMaps/clsBenefitJurisdictionCodeMap.vb |

---

## BR-POL-013 Manual class type code recognition

| Field | Value |
| --- | --- |
| **Statement** | Only manual class type codes `"D"`, `"F"`, `"M"`, `"FELA"`, `"R"`, `"U"` are recognised; other rows in `MANUAL_CLASS_TYPE_CODE` are ignored. |
| **Trigger** | Code map construction (`CodeMaps.GetManualClassTypeCodeMap`) |
| **Enforcement** | `clsManualClassTypeCodeMap.New` |
| **Outcome** | Unrecognised codes are absent from the map. |
| **Tables** | [MANUAL_CLASS_TYPE_CODE](database-tables.md#manual_class_type_code) |
| **SQL** | [SQL-003](sql/SQL-003-manual-class-type-code-lookup.md) |
| **Source** | SAIF.Business.Policy/CodeMaps/clsManualClassTypeCodeMap.vb |

---

## BR-POL-014 Translation confidence scale

| Field | Value |
| --- | --- |
| **Statement** | Translation confidence is graded on a fixed scale: exact match `100`, most likely `75`, default `10`, failure `0`; a new result defaults to `Failure`. |
| **Trigger** | Construction/use of `clsTranslationResult` |
| **Enforcement** | `clsTranslationResult.Accuracies` and field initialiser |
| **Outcome** | Consumers can rank translation quality consistently. |
| **Source** | SAIF.Business.Policy/clsTranslationResult.vb |

---

## BR-POL-015 Rating period market-type classification

| Field | Value |
| --- | --- |
| **Statement** | A rating period is Voluntary when its market type is `Voluntary` and Assigned Risk when its market type is `AssignedRisk`. |
| **Trigger** | `IsVoluntary` / `IsAssignedRisk` |
| **Enforcement** | `PeriodRatingInfoExtensions` |
| **Outcome** | Single definition of the market-type test for all implementers. |
| **Source** | SAIF.Business.Policy/iPeriodRatingInfo.vb |

---

## BR-POL-016 Code map caching

| Field | Value |
| --- | --- |
| **Statement** | Code maps are built once per process and reused until an explicit `refresh` is requested.* |
| **Trigger** | `CodeMaps.Get*CodeMap` |
| **Enforcement** | `Static` cached fields in the partial `CodeMaps` class |
| **Outcome** | Code table rows are read once; later code-table changes are not seen until refresh/restart.* |
| **Source** | SAIF.Business.Policy/CodeMaps/clsBenefitJurisdictionCodeMap.vb, SAIF.Business.Policy/CodeMaps/clsManualClassTypeCodeMap.vb |

---

## BR-POL-017 Code enum conversion fallback

| Field | Value |
| --- | --- |
| **Statement** | Every code→enum conversion falls back to the enum's `Unknown`/`Unassigned` member, and every enum→code conversion falls back to an empty string. |
| **Trigger** | Any `Enums.Convert*` call |
| **Enforcement** | `Enums.Convert*` `Select Case ... Case Else` blocks |
| **Outcome** | Unrecognised codes never raise; they degrade to a neutral value. |
| **Source** | SAIF.Business.Policy/Enums.vb |

---

## BR-POL-018 Rating period equality

| Field | Value |
| --- | --- |
| **Statement** | Two rating periods are equal only when anniversary rating date, rating effective date, ARD-extended flag, RED-extended flag, effective date, expiration date, rate tier code and market type all match. |
| **Trigger** | `BaseEquals` / `BaseGetHashCode` |
| **Enforcement** | `PeriodRatingInfoExtensions.BaseEquals` |
| **Outcome** | Uniform rating-period comparison semantics across implementers. |
| **Source** | SAIF.Business.Policy/iPeriodRatingInfo.vb |

---

## BR-POL-019 Association type visibility declaration

| Field | Value |
| --- | --- |
| **Statement** | Association types expose the name of the Active Directory group that gates their visibility, and the stored procedure that sources their policy set. |
| **Trigger** | Implementation of `IPolicyAssociationType` by a consuming library |
| **Enforcement** | `IPolicyAssociationType.SecurityGroupName`, `.SourceStoredProcedureName` |
| **Outcome** | Declaration only; this library performs no authorization check itself. |
| **Source** | SAIF.Business.Policy/IPolicyHeaderDataProvider.vb |

## Stored procedure business rules

Rules sourced from Oracle stored procedures referenced by this library.

| Rule ID | Rule | Source | Link |
| --- | --- | --- | --- |
| PR-BP-001 | Minimum-premium calculation is routed by market type: voluntary business uses the VOL minimum-premium rules; all other market types use the ARP (assigned-risk) minimum/expense-constant calculation. | `pk73069_rating_procs.get_minimum_expense_constant` | [Details](procedures/pk73069-rating-procs.md#business-rules) |
| PR-BP-002 | A voluntary policy that belongs to a combination (combo) period has its minimum premium calculated at the combination level rather than the individual policy level. | `pk73069_rating_procs.get_minimum_expense_constant` | [Details](procedures/pk73069-rating-procs.md#business-rules) |
| PR-BP-003 | Voluntary policy periods effective before 01-Apr-2010 receive a fixed minimum premium of 500; on or after that date the minimum is variable and derived from rating data. | `pk73069_rating_procs.get_vol_policy_minimum` (reached via `get_minimum_expense_constant`) | [Details](procedures/pk73069-rating-procs.md#business-rules) |
| PR-BP-004 | From 01-Jan-2014 onward the voluntary minimum is calculated identically regardless of premium-history set type; before that date, set type `'1'` is treated differently from all other set types. | `pk73069_rating_procs.get_vol_policy_minimum` (reached via `get_minimum_expense_constant`) | [Details](procedures/pk73069-rating-procs.md#business-rules) |
| PR-BP-005 | Any unhandled failure in minimum/expense-constant calculation is converted into an application error by the central error handler; it is not silently ignored at the database layer. | `pk73069_rating_procs.get_minimum_expense_constant` | [Details](procedures/pk73069-rating-procs.md#business-rules) |
| PR-BP-006 | WCIS ownership of a policy submission is determined by the `wcis_owns_flag` on the submission-status code currently assigned to the policy's sub-policy record. | `pk73102_policy.does_wcis_own_submission` | [Details](procedures/pk73102-policy.md#business-rules) |
| PR-BP-007 | When ownership cannot be determined — no matching sub-policy/status row, or any other error — the policy defaults to being owned by WCIS. | `pk73102_policy.does_wcis_own_submission` | [Details](procedures/pk73102-policy.md#business-rules) |

## Notes
- No cross-repository consumer was found for most types in this library other than the policy-association contract family, consumed by `SAIF.Business.View.Policy`.*
- Both stored procedures referenced by BR-POL-005 and BR-POL-008 (`pk73102_policy.does_wcis_own_submission`, `pk73069_rating_procs.get_minimum_expense_constant`) were retrieved successfully via the Legends CLI; see [Stored procedure business rules](#stored-procedure-business-rules) below and their [detail pages](procedures/index.md) for the additional rules extracted from their PL/SQL bodies.

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [Procedures](procedures/index.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Business.Policy/PolicyInformation.vb`
- `SAIF.Business.Policy/clsHazardGroup.vb`
- `SAIF.Business.Policy/clsHazardGroupCollection.vb`
- `SAIF.Business.Policy/CodeMaps/clsBenefitJurisdictionCodeMap.vb`
- `SAIF.Business.Policy/CodeMaps/clsManualClassTypeCodeMap.vb`
- `SAIF.Business.Policy/Enums.vb`
- `SAIF.Business.Policy/PeriodRatingInfoExtensions.vb`
